"""
Copyright (c) 2022 Huawei Technologies Co.,Ltd.

openGauss is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:

          http://license.coscl.org.cn/MulanPSL2

THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
"""
"""
Case Type   : 配置文件
Case Name   : 运行/停止时清空配置文件内容
Create At   : 2020/06/30
Owner       : n@ningyali
Description :
    1.启动/停止数据库
    2.清空配置文件内容
    3.执行sql并行脚本，正常运行
    4.停止/启动数据库
    5.还原配置文件
Expect      :
    1.成功
    2.成功
    3.成功
    4.失败
    5.成功
History     :
    modified: 2020/12/20  modified by @peilinqian, postgresql.conf的备份文件安装完成默认为
        postgresql.conf.guc.bak，修改还原操作
    modified by @haomeng802 at 2022/12/27:修改还原postgresql.conf.guc.bak文件操作
    modified by @peilinqian at 2023/5/23:优化conf文件备份操作，优化整体用例逻辑
"""

import os
import unittest

from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from testcase.utils.Logger import Logger
from yat.test import Node
from yat.test import macro


class EmptyConfFile(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.log = Logger()
        cls.log.info(f'----{os.path.basename(__file__)}:start----')
        cls.rootNode = Node()
        cls.dbUserNode = Node(node='dbuser')
        cls.conf_file_path = os.path.join(macro.DB_INSTANCE_PATH,
                                          macro.DB_PG_CONFIG_NAME)
        cls.bak_file_path = os.path.basename(
            cls.conf_file_path) + '.case088.bak'
        cls.com = Common()
        cls.Constant = Constant()
        cls.sh = CommonSH()
        cls.sqlfile1 = 'bx1.sql'
        cls.sqlfile2 = 'bx2.sql'
        cls.to_path = os.path.join(os.path.dirname(macro.DB_INSTANCE_PATH),
                                   'test_script')

    def setUp(self):
        self.log.info('----this is setup----')
        step_txt = '----step1：检查数据库状态; expect:状态正常----'
        self.log.info(step_txt)
        db_status = self.sh.getDbClusterStatus('status')
        if not db_status:
            self.sh.startDbCluster()

            db_status = self.sh.getDbClusterStatus('status')
            if not db_status:
                raise Exception("db status is not true, please check!")
        self.log.info(db_status)

        step_txt = '----step2：备份postgres.conf文件; expect:备份成功----'
        self.log.info(step_txt)
        self.bak_file = os.path.join(os.path.dirname(self.conf_file_path),
                                     self.bak_file_path)
        bak_cmd = f'cp {self.conf_file_path} {self.bak_file}'
        self.log.info(bak_cmd)
        msg = self.dbUserNode.sh(bak_cmd).result()
        self.assertEqual(msg, '', '执行失败:' + step_txt)

    def test_1_empty_conf_to_stop(self):
        self.log.info('----用例1：清空配置文件后停止数据库----')
        step_txt = '----step1：清空配置文件内容; expect:清空成功----'
        self.log.info(step_txt)
        empty_cmd = f"> {self.conf_file_path}"
        self.log.info(empty_cmd)
        empty_msg = self.dbUserNode.sh(empty_cmd).result()
        self.log.info(empty_msg)
        self.assertEqual(empty_msg, '', '执行失败:' + step_txt)

        self.log.info('----拷贝SQL文件----')
        self.newsql_path1 = os.path.join(self.to_path, self.sqlfile1)
        self.newsql_path2 = os.path.join(self.to_path, self.sqlfile2)
        self.com.scp_file(self.rootNode, self.sqlfile1, self.to_path)
        self.com.scp_file(self.rootNode, self.sqlfile2, self.to_path)

        step_txt = '----step2：执行sql并行脚本; expect:脚本运行正常----'
        self.log.info(step_txt)
        sql_bx_cmd = f"source {macro.DB_ENV_PATH};" \
            f"gsql -d {self.dbUserNode.db_name} " \
            f"-p {self.dbUserNode.db_port} -U '{self.dbUserNode.db_user}' " \
            f"-W '{self.dbUserNode.db_password}' -f {self.newsql_path1} &\n" \
            f"gsql -d {self.dbUserNode.db_name} " \
            f"-p {self.dbUserNode.db_port} -U '{self.dbUserNode.db_user}' " \
            f"-W '{self.dbUserNode.db_password}' -f {self.newsql_path2} &\n" \
            f"wait"
        self.log.info(sql_bx_cmd)
        sql_bx_msg = self.dbUserNode.sh(sql_bx_cmd).result()
        self.log.info(sql_bx_msg)
        self.assertNotIn('ERROR', sql_bx_msg, '执行失败:' + step_txt)
        self.assertEqual(sql_bx_msg.count('1 row'), 2, '执行失败:' + step_txt)

        step_txt = '----step3：清空配置文件内容后,停止数据库; expect:停止成功----'
        self.log.info(step_txt)
        stop_msg = self.sh.stopDbCluster()
        self.assertTrue(stop_msg, '执行失败:' + step_txt)

    def test_2_empty_conf_to_start(self):
        self.log.info('----用例2：清空配置文件后启动数据库----')
        step_txt = '----step1：停止数据库; expect:停止成功----'
        self.log.info(step_txt)
        stop_msg = self.sh.stopDbCluster()
        self.assertTrue(stop_msg, '执行失败:' + step_txt)

        step_txt = '----step2：清空配置文件内容; expect:清空成功----'
        self.log.info(step_txt)
        empty_cmd = f"> {self.conf_file_path}"
        self.log.info(empty_cmd)
        empty_msg = self.dbUserNode.sh(empty_cmd).result()
        self.log.info(empty_msg)
        self.assertEqual(empty_msg, '', '执行失败:' + step_txt)
        self.log.info('----查询配置文件大小----')
        cmd = f"ls -lh {self.conf_file_path}"
        self.log.info(cmd)
        msg = self.dbUserNode.sh(cmd).result()
        self.log.info(msg)

        step_txt = '----step3：清空配置文件内容后,启动数据库; expect:启动失败----'
        self.log.info(step_txt)
        start_msg = self.sh.startDbCluster()
        self.assertFalse(start_msg, '执行失败:' + step_txt)

    def tearDown(self):
        self.log.info('----this is teardown----')
        step_txt = '----还原配置文件; expect:还原成功----'
        self.log.info(step_txt)
        recover_cmd = f'cp {self.bak_file} {self.conf_file_path};' \
            f'rm -rf {self.bak_file}'
        self.log.info(recover_cmd)
        msg = self.dbUserNode.sh(recover_cmd).result()
        self.assertEqual(msg, '', '执行失败:' + step_txt)

        step_txt = '----重启数据库; expect:重启成功----'
        self.log.info(step_txt)
        self.sh.stopDbCluster()
        self.sh.startDbCluster()
        db_status = self.sh.getDbClusterStatus('status')
        self.assertTrue(db_status, '执行失败:' + step_txt)

    @classmethod
    def tearDownClass(cls):
        cls.log.info('----删除scp的脚本----')
        cls.com.scp_file(cls.rootNode, cls.sqlfile1, cls.to_path, True)
        cls.com.scp_file(cls.rootNode, cls.sqlfile2, cls.to_path, True)
        cls.log.info(f'----{os.path.basename(__file__)}:end----')
